********************************************************************************
**************    Code for umbrella review on binary outcomes     **************
********************************************************************************
**  Programmers: Georgios Markozannes, Afroditi Kanellopoulou                 **
**  Stata/MP 14.0 for Windows (64-bit)                                        **
**                                                                            **
**  Stata ado files required:                                                 **
**   metan                                                                    **
**   metabias                                                                 **
**   heterogi                                                                 **                                               
**                                                                            **                                                        
**  Minimum set of variables required for this analysis                       **
**   compid		ID number of each comparison, used for the loops      **
**   Cohort		Sample size in primary study			      **
**   No_cases           Number of cases in primary study                      **
**   N_controls        	Number of controls in primary study                   **
**   RR                	Effect size (OR, RR, HR etc., NOT beta, MD, XMD, etc,)**
**   Low_CI_level       Lower 95% confidence interval                 	      **
**   Up_CI_level        Upper 95% confidence interval                         **
**                                                                            **
********************************************************************************
********************************************************************************

import excel dataset_umbrella_diet_cancer.xls, firstrow clear

********************************************************************************
********************************************************************************
***************		Wider exposure categories		****************
********************************************************************************
********************************************************************************

replace Exposure=trim(Exposure)

* Wider exposure categories
gen Exposure_wider=11
replace Exposure_wider=1 if regexm(Exposure, "Alcohol")==1 | ///
regexm(Exposure, "alcohol")==1 | regexm(Exposure, "Ethanol")==1 | ///
regexm(Exposure, "Beer")==1 | regexm(Exposure, "beer")==1 | ///
regexm(Exposure, "Liquor")==1 | regexm(Exposure, "liquor")==1 | ///
regexm(Exposure, "Wine")==1 | regexm(Exposure, "wine")==1 | ///
regexm(Exposure, "sake")==1 | regexm(Exposure, "Sake")==1 | ///
regexm(Exposure, "Spirit")==1 | regexm(Exposure, "spirit")==1
replace Exposure_wider=2 if regexm(Exposure, "Coffee")==1 | ///
regexm(Exposure, "coffee")==1 | regexm(Exposure, "Tea")==1 | ///
regexm(Exposure, "tea")==1 | regexm(Exposure, "fluid")==1
replace Exposure_wider=3 if regexm(Exposure, "Carbohydrate")==1 | ///
regexm(Exposure, "carbohydrate")==1 | regexm(Exposure, "Energy")==1 | ///
regexm(Exposure, "energy")==1 | regexm(Exposure, "Fructose")==1 | ///
regexm(Exposure, "fructose")==1 | regexm(Exposure, "Sucrose")==1 | ///
regexm(Exposure, "sucrose")==1 | regexm(Exposure, "Sugar")==1 | ///
regexm(Exposure, "sugar")==1
replace Exposure_wider=4 if regexm(Exposure, "index")==1 | regexm(Exposure, "load")==1
replace Exposure_wider=5 if regexm(Exposure, "salt")==1
replace Exposure_wider=6 if regexm(Exposure, "Meat")==1 | regexm(Exposure, "meat")==1 | ///
regexm(Exposure, "Fish")==1 | regexm(Exposure, "fish")==1 | ///
regexm(Exposure, "Poultry")==1 | regexm(Exposure, "poultry")==1 | ///
regexm(Exposure, "Egg")==1 | regexm(Exposure, "egg")==1
replace Exposure_wider=7 if regexm(Exposure, "Fat")==1 | regexm(Exposure, "fat")==1
replace Exposure_wider=8 if regexm(Exposure, "Cheese")==1 | ///
regexm(Exposure, "cheese")==1 | regexm(Exposure, "Milk")==1 | ///
regexm(Exposure, "milk")==1 | regexm(Exposure, "Dairy")==1 | ///
regexm(Exposure, "dairy")==1 | regexm(Exposure, "Yoghurt")==1 | ///
regexm(Exposure, "yoghurt")==1
replace Exposure_wider=9 if regexm(Exposure, "Legumes")==1 | regexm(Exposure, "legumes")==1 | ///
regexm(Exposure, "Soy")==1 | regexm(Exposure, "soy")==1 | regexm(Exposure, "Soya")==1 | ///
regexm(Exposure, "soya")==1 | regexm(Exposure, "Miso")==1 | regexm(Exposure, "miso")==1 | ///
regexm(Exposure, "Tofu")==1 | regexm(Exposure, "tofu")==1
replace Exposure_wider=10 if regexm(Exposure, "Grain")==1 | regexm(Exposure, "grain")==1
replace Exposure_wider=12 if regexm(Exposure, "Calcium")==1 | ///
regexm(Exposure, "calcium")==1 | regexm(Exposure, "Selenium")==1 | ///
regexm(Exposure, "selenium")==1 | regexm(Exposure, "Iron")==1 | ///
regexm(Exposure, "iron")==1
replace Exposure_wider=13 if regexm(Exposure, "Carot")==1 | ///
regexm(Exposure, "carot")==1 | regexm(Exposure, "Beta-cryptoxanthin")==1 | ///
regexm(Exposure, "beta-cryptoxanthin")==1 | regexm(Exposure, "Lycopene")==1 | ///
regexm(Exposure, "lycopene")==1 | regexm(Exposure, "Lutein")==1 | ///
regexm(Exposure, "lutein")==1 | regexm(Exposure, "Isoflavone")==1 | ///
regexm(Exposure, "isoflavone")==1 | regexm(Exposure, "Garlic")==1
replace Exposure_wider=14 if regexm(Exposure, "Fibre")==1 | regexm(Exposure, "fibre")==1
replace Exposure_wider=15 if regexm(Exposure, "Folic")==1 | regexm(Exposure, "folic")==1 | ///
regexm(Exposure, "Folate")==1 | regexm(Exposure, "folate")==1
replace Exposure_wider=16 if regexm(Exposure, "Vitamin D")==1 | ///
regexm(Exposure, "vitamin D")==1
replace Exposure_wider=17 if regexm(Exposure, "Vitamin C")==1 | ///
regexm(Exposure, "vitamin C")==1 | regexm(Exposure, "Vitamin E")==1 | ///
regexm(Exposure, "vitamin E")==1 | regexm(Exposure, "Vitamin B6")==1 | ///
regexm(Exposure, "vitamin B6")==1 | regexm(Exposure, "Multivitamin")==1 | ///
regexm(Exposure, "multivitamin")==1 | regexm(Exposure, "Retinol")==1 | ///
regexm(Exposure, "retinol")==1

label define exposure_wider_lab 1 "Alcohol" 2 "Beverages" 3 "Energy and sugars" ///
4 "Glycaemic index/load" 5 "Salt and salty foods" 6 "Meat and eggs" ///
7 "Fats and fatty acids" 8 "Dairy products" 9 "Legumes and soy products" 10 "Grains" ///
11 "Fruits and vegetables" 12 "Minerals" 13 "Phytochemicals" 14 "Fibre" ///
15 "Folate" 16 "Vitamin D" 17 "Other vitamins and supplements"
label values Exposure_wider exposure_wider_lab

replace Exposure_wider=7 if Exposure=="Dietary n-3 fatty acid from Fish"
replace Exposure_wider=11 if regexm(Exposure, "veggies")==1

********************************************************************************
********************************************************************************
*******************		Data manipulation		****************
********************************************************************************
********************************************************************************

egen compid=group(Exposure Exposure_contrast Outcome Cancer)
drop if compid==.
gen count=.
bysort compid: replace count=_N

rename No_of_population Cohort
rename No_of_Cases No_cases
gen N_controls=Cohort-No_cases

gen Study_logRR=log(RR)
gen Study_logLL=log(Low_CI_level)
gen Study_logUL=log(Up_CI_level)
gen se=(Study_logUL-Study_logLL)/(2*invnormal(0.975))

*Correct the se in the study of Tiemersma
replace se=2.0746165 if Author_year=="Tiemersma, 2002" & Exposure=="Fish" & ///
Outcome=="colorectal cancer women"
replace Study_logLL=Study_logRR-invnormal(0.975)*se if Author_year=="Tiemersma, 2002" & ///
Exposure=="Fish" & Outcome=="colorectal cancer women"

gen Study_var=se^2
bysort compid: egen minse=min(se)

* Create global variable to use in the loops
quietly levelsof compid
global compid_levels `r(levels)'

********************************************************************************
********************************************************************************     
****   Count number of cases / sample size per compid                 	    ****																					
********************************************************************************
********************************************************************************

egen total_N=total(Cohort), by(compid)
egen total_Cases=total(No_cases), by(compid)
egen total_Controls=total(N_controls), by(compid)

********************************************************************************
********************************************************************************
****   Compute fixed and random effects, Egger's test, heterogeneity and    ****
****   corresponding CI, prediction intervals and  excess significance      ****
********************************************************************************
********************************************************************************

*********************
* Fixed-effects MA  *
*********************

quietly gen effectfix=.
quietly gen effectfix_l=.
quietly gen effectfix_u=.
quietly gen double pfix=.

quietly gen egger_p=.
quietly gen egger_slope=.
quietly gen egger_slope_p=.
quietly gen I2=.
quietly gen I2_lb=.
quietly gen I2_ub=.
quietly gen I2_p=.

* Fixed-effects metrics needed for conditional power
quietly gen feW=1/Study_var
quietly gen feW2=feW^2
quietly gen feWY=feW*Study_logRR
quietly bysort compid: egen Study_var_bar=mean(Study_var)
quietly bysort compid: egen feW_sum=sum(feW)
quietly bysort compid: egen feW_bar=mean(feW)
quietly bysort compid: egen feW2_sum=sum(feW2)
quietly bysort compid: egen feWY_sum=sum(feWY)

quietly levelsof compid if count>2, local(compid2)
	foreach i of local compid2 {
	
* Egger test 
quietly metabias Study_logRR se if compid==`i', egger 
quietly replace egger_p=r(p_bias) if compid==`i'
quietly replace egger_slope=exp(_b[slope]) if compid==`i'
quietly replace egger_slope_p=2*ttail(e(df_r), abs(_b[slope]/_se[slope])) if compid==`i'

quietly metan Study_logRR se if compid==`i', nograph eform
quietly replace effectfix=r(ES) if compid==`i'
quietly replace effectfix_l=r(ci_low) if compid==`i'
quietly replace effectfix_u=r(ci_upp) if compid==`i'
quietly replace pfix=r(p_z) if compid==`i'
quietly replace I2=r(i_sq)/100 if compid==`i'
quietly replace I2_p=r(p_het) if compid==`i'	

* CI for I squared
quietly heterogi r(het) r(df), nc
quietly replace I2_lb=r(lb_I2_M2) if compid==`i'
quietly replace I2_ub=r(ub_I2_M2) if compid==`i'

}
		
* If meta-analyses with 2 studies are included, otherwise skip
quietly levelsof compid if count<=2, local(compid3)
	foreach i of local compid3 {
	
quietly metan Study_logRR se if compid==`i',nograph eform 
quietly replace effectfix=r(ES) if compid==`i'
quietly replace effectfix_l=r(ci_low) if compid==`i'
quietly replace effectfix_u=r(ci_upp) if compid==`i'
quietly replace pfix=r(p_z) if compid==`i'
quietly replace I2=r(i_sq)/100 if compid==`i'
	
}

*********************
* Random-effects MA *
*********************

quietly gen pred_ll=.
lab var pred_ll "Prediction L.CI"
quietly gen pred_ul=.
lab var pred_ul "Prediction U.CI"

quietly gen effectrandom=.
quietly gen effectrandom_l=.
quietly gen effectrandom_u=.
quietly gen float p_het=.
quietly gen double prandom=.
quietly gen Study_RE_RR=.
quietly gen tau=.

* Random-effects metrics needed for conditional power
quietly gen reW=.
quietly gen reW_sum=.
quietly gen reWY=.
quietly gen reWY_sum=.

sort compid

	foreach i of global compid_levels {
	
quietly metan Study_logRR se if compid==`i', nograph random eform
quietly replace effectrandom=r(ES) if compid==`i'
quietly replace effectrandom_l=r(ci_low) if compid==`i'
quietly replace effectrandom_u=r(ci_upp) if compid==`i'
quietly replace prandom=r(p_z) if compid==`i'
quietly replace Study_RE_RR=round(r(ES),0.01) if compid==`i'
quietly replace tau=r(tau2) if compid==`i'

* Prediction intervals
quietly replace pred_ll= exp(log(effectrandom)- invttail(r(df)-1,0.025)*sqrt(r(selogES)^2+ tau)) if compid==`i' & count>2
quietly replace pred_ul= exp(log(effectrandom)+ invttail(r(df)-1,0.025)*sqrt(r(selogES)^2+ tau)) if compid==`i' & count>2

quietly replace reW=1/(Study_var+tau) if compid==`i'
quietly sum reW if compid==`i'
quietly replace reW_sum=r(sum) if compid==`i'
quietly replace reWY=reW*Study_logRR if compid==`i'
quietly sum reWY if compid==`i'
quietly replace reWY_sum=r(sum) if compid==`i'

}

*****************
* Largest study	*
*****************

* Critical value per study based on sample size
quietly gen t=invttail(Cohort,0.025)

quietly gen effect_largstu=.
quietly gen effect_largstu_l=.
quietly gen effect_largstu_u=.

quietly sort compid se Cohort /*Cohort (size) 3rd term if two or more studies have the same se*/
quietly by compid: replace effect_largstu=RR[1]
quietly by compid: replace effect_largstu_l=Low_CI_level[1]
quietly by compid: replace effect_largstu_u=Up_CI_level[1]

quietly gen log_effect_largstu=log(effect_largstu)
quietly gen wmdrandom_largstu=log_effect_largstu/1.81
quietly gen deltarandom_largstu=wmdrandom_largstu*sqrt((No_cases*N_controls)/(No_cases+N_controls))
quietly gen powerrandom_largstu=nFtail(1,Cohort,deltarandom_largstu^2,t^2)

* Few obs got a missing value on power - replace all missing to 0.99999
replace powerrandom_largstu=0.99999 if powerrandom_largstu==. | powerrandom_largstu==1

* Number of studies
quietly egen NoStudies=count(compid), by(compid)
lab var NoStudies "#Studies"
replace I2=I2*100
replace I2_lb=I2_lb*100
replace I2_ub=I2_ub*100
replace I2=0 if NoStudies==1 & I2==100
drop if count==1

********************************************************************************
********************************************************************************
**** 			Excess significance manual estimation               ****
********************************************************************************
********************************************************************************

* Generate indicator of whether a study is statisticall significat or not
gen statSig0=(abs(Study_logRR)-abs(invnorm(.025))*se)>0

* Few obs got a power of 1 - replace all 1 to 0.99999, as power=1 induces an error
quietly replace powerrandom_largstu=0.99999 if powerrandom_largstu==1

gen excess_sig_count1=.
gen Expected1=.
gen Observed1=.
gen pBin1=.

* Based on the effect estimate of the largest study as the plausible effect estimate
* used for the power calculation
quietly levelsof compid, local(compid4)

	foreach i of local compid4 {

quietly sum statSig0 if compid==`i' & powerrandom_largstu!=.
local observed=r(sum)
local studies=r(N)
quietly sum powerrandom_largstu if compid==`i' & powerrandom_largstu!=.
local expected=r(sum)
local power=r(sum)/r(N)

quietly bitesti `studies' `observed' `power' 

local chi=(`observed'-`expected')^2/`expected' + (`observed'-`expected')^2/(`studies'-`expected')
local chi_p=1-chi2(1,`chi')

quietly replace excess_sig_count1=`studies' if compid==`i'
quietly replace Expected1=`expected' if compid==`i'
quietly replace Observed1=`observed' if compid==`i'
quietly replace pBin1=`r(p)' if compid==`i'

}

********************************************************************************
********************************************************************************
**** 	 		Grading of the evidence                		    ****
********************************************************************************
********************************************************************************

* To add code for the case where egger_p<0.1 and whether the random effects summary 
* estimate was larger than the point estimate of the largest study in the meta-analysis

quietly gen grade=.

replace pBin1=. if Observed1<=Expected1
quietly replace grade=1 if (Observed1<=Expected1 | (Observed1>Expected1  & pBin1>0.1 & pBin1<.)) & ///
((pred_ll<1 & pred_ul<1) | (pred_ll>1 & pred_ul>1)) & ///
I2<50 & total_Cases>=1000 & prandom<1E-06 & ///
(egger_p>0.1 | (egger_p<=0.1 & abs(log(effectrandom))<=abs(log(effect_largstu))))
quietly replace grade=2 if prandom<1E-06 & total_Cases>=1000 & (effect_largstu_l>1 | ///
effect_largstu_u<1) & grade==.
quietly replace grade=3 if prandom<1E-03 & total_Cases>=1000 & grade==.
quietly replace grade=4 if prandom<0.05 & grade==.
quietly replace grade=5 if grade==.
quietly lab define grading 1 "Strong" 2 "Highly suggestive" 3 "Suggestive" 4 "Weak" 5 "NS"
quietly lab val grade grading

********************************************************************************
********************************************************************************
**** 		Conditional power using the RE summary estimate             ****
********************************************************************************
********************************************************************************

*********************************************************************
* Each study included in a pooled project will be considered as an  *
*				independent study		    *
*********************************************************************

* Breast 
replace count=33 if Outcome=="Breast cancer (CUP and Pooling Project)" & Exposure=="alcohol intake" & count==14
replace count=23 if Outcome=="Breast Cancer" & Exposure=="alcohol intake from beer" & count==5
replace count=29 if Outcome=="Breast Cancer post (CUP and Pooling Project)" & Exposure=="alcohol intake" & count==10
replace count=24 if Outcome=="Breast Cancer" & Exposure=="alcohol intake from wine" & count==5
replace count=11 if Outcome=="Breast Cancer" & Exposure=="energy from saturated fat" & count==4
replace count=11 if Outcome=="Breast Cancer" & Exposure=="circulating beta-carotene concentration" & count==4
replace count=12 if Outcome=="Breast Cancer" & Exposure=="saturated fat intake" & count==6
replace count=9 if Outcome=="Breast Cancer" & Exposure=="circulating total carotenoid concentration" & count==2
replace count=17 if Outcome=="Breast Cancer post" & Exposure=="total fat intake" & count==8
replace count=23 if Outcome=="Breast Cancer" & Exposure=="alcohol from liquor intake" & count==4
replace count=9 if Outcome=="Breast Cancer" & Exposure=="poultry intake" & count==3
replace count=10 if Outcome=="Breast Cancer" & Exposure=="plasma alpha-carotene concentration" & count==3
replace count=6 if Outcome=="Breast Cancer pre" & Exposure=="energy from saturated fat" & count==2
replace count=18 if Outcome=="Breast Cancer pre (CUP and Pooling Project)" & Exposure=="alcohol intake" & count==4
replace count=21 if Outcome=="Breast Cancer ER+PR+" & Exposure=="dietary folate intake" & count==2
replace count=13 if Outcome=="Breast Cancer" & Exposure=="processed meat intake" & count==7
replace count=13 if Outcome=="Breast Cancer" & Exposure=="energy from fat" & count==6
replace count=10 if Outcome=="Breast Cancer post" & Exposure=="polyunsaturated fatty acids intake" & count==7
replace count=10 if Outcome=="Breast Cancer" & Exposure=="circulating beta-cryptoxanthin concentration" & count==3
replace count=11 if Outcome=="Breast Cancer post" & Exposure=="saturated fat intake" & count==8
replace count=16 if Outcome=="Breast Cancer post" & Exposure=="energy from polyunsaturated fatty acids" & count==6
replace count=12 if Outcome=="Breast Cancer" & Exposure=="total fat intake" & count==6
replace count=10 if Outcome=="Breast Cancer" & Exposure=="circulating lycopene concentration" & count==3
replace count=6 if Outcome=="Breast Cancer pre" & Exposure=="energy from polyunsaturated fatty acids" & count==2
replace count=14 if Outcome=="Breast Cancer" & Exposure=="total milk intake" & count==7
replace count=12 if Outcome=="Breast Cancer" & Exposure=="monounsaturated fatty acids intake" & count==6
replace count=11 if Outcome=="Breast Cancer" & Exposure=="polyunsaturated fatty acids intake" & count==5
replace count=12 if Outcome=="Breast Cancer" & Exposure=="whole milk intake" & count==5
replace count=12 if Outcome=="Breast Cancer" & Exposure=="energy from monounsaturated fatty acids" & count==5
replace count=10 if Outcome=="Breast Cancer" & Exposure=="total red meat intake" & count==3
replace count=16 if Outcome=="Breast Cancer" & Exposure=="total fish intake" & count==8
replace count=16 if Outcome=="Breast Cancer post" & Exposure=="energy from saturated fat" & count==6
replace count=6 if Outcome=="Breast Cancer pre" & Exposure=="energy from monounsaturated fatty acids" & count==2
replace count=16 if Outcome=="Breast Cancer post" & Exposure=="energy from monounsaturated fatty acids" & count==6
replace count=10 if Outcome=="Breast Cancer post" & Exposure=="energy from fat" & count==7
replace count=21 if Outcome=="Breast Cancer ER-PR-" & Exposure=="dietary folate intake" & count==2
replace count=9 if Outcome=="Breast Cancer post" & Exposure=="total red meat intake" & count==2
replace count=11 if Outcome=="Breast Cancer post" & Exposure=="monounsaturated fatty acids intake" & count==8
replace count=12 if Outcome=="Breast Cancer" & Exposure=="energy from polyunsaturated fatty acids" & count==5

* Colorectal

* One study was not used in the meta-analysis rectal+total carbohydrate
drop if Author_year=="Howarth, 2008" & Exposure=="Total carbohydrate" & Outcome=="rectal cancer" & RR==0.93

* One duplicate observation based on all variables
duplicates drop

replace count=16 if Outcome=="colorectal cancer" & Exposure=="Alcohol (as ethanol)" & count==12
replace count=25 if Outcome=="colorectal cancer" & Exposure=="Dietary calcium intake" & count==16
replace count=14 if Outcome=="colon cancer" & Exposure=="Alcohol (as ethanol)" & count==10
replace count=14 if Outcome=="colorectal cancer men" & Exposure=="Alcohol (as ethanol)" & count==10
replace count=11 if Outcome=="rectal cancer" & Exposure=="Alcohol (as ethanol)" & count==7
replace count=12 if Outcome=="colon cancer men" & Exposure=="Alcohol (as ethanol)" & count==8
replace count=10 if Outcome=="rectal cancer men" & Exposure=="Alcohol (as ethanol)" & count==6
replace count=8 if Outcome=="rectal cancer women" & Exposure=="Alcohol (as ethanol)" & count==4
replace count=10 if Outcome=="colon cancer women" & Exposure=="Alcohol (as ethanol)" & count==6
replace count=10 if Outcome=="colorectal cancer women" & Exposure=="Alcohol (as ethanol)" & count==6
replace count=21 if Outcome=="colon cancer" & Exposure=="Dietary fibre" & count==9
replace count=17 if Outcome=="colorectal cancer" & Exposure=="Cereal fibre" & count==5
replace count=21 if Outcome=="colorectal cancer" & Exposure=="Dietary fibre" & count==9
replace count=21 if Outcome=="rectal cancer" & Exposure=="Dietary fibre" & count==9
replace count=18 if Outcome=="colorectal cancer" & Exposure=="Fruit fibre" & count==6
replace count=16 if Outcome=="proximal colon cancer" & Exposure=="Tea consumption" & count==4
replace count=17 if Outcome=="colon cancer" & Exposure=="Dietary folate" & count==5
replace count=10 if Outcome=="colon cancer" & Exposure=="Total folate" & count==3
replace count=23 if Outcome=="colon cancer" & Exposure=="Coffee consumption" & count==11
replace count=18 if Outcome=="colorectal cancer" & Exposure=="Vegetable fibre" & count==6
replace count=17 if Outcome=="distal colon cancer" & Exposure=="Coffee consumption" & count==5
replace count=18 if Outcome=="colon cancer" & Exposure=="Tea consumption" & count==6
replace count=17 if Outcome=="proximal colon cancer" & Exposure=="Coffee consumption" & count==5
replace count=16 if Outcome=="distal colon cancer" & Exposure=="Tea consumption" & count==4
replace count=15 if Outcome=="colon cancer" & Exposure=="Vitamin E" & count==3
replace count=9 if Outcome=="rectal cancer" & Exposure=="Total carbohydrate" & count==11

* Head and neck
replace count=22 if Outcome=="Pharyngeal cancer" & Exposure=="Fruit" & count==3
replace count=22 if Outcome=="Oral cancer" & Exposure=="Vegetable" & count==3
replace count=22 if Outcome=="Pharyngeal cancer" & Exposure=="Vegetable" & count==3
replace count=22 if Outcome=="Oral cancer" & Exposure=="Fruit" & count==3
replace count=23 if Outcome=="Head and Neck cancer" & Exposure=="Vegetable" & count==4
replace count=22 if Outcome=="Laryngeal cancer" & Exposure=="Vegetable" & count==3
replace count=22 if Outcome=="Head and Neck cancer" & Exposure=="Citrus fruit" & count==3
replace count=23 if Outcome=="Head and Neck cancer" & Exposure=="Fruit" & count==4
replace count=22 if Outcome=="Laryngeal cancer" & Exposure=="Fruit" & count==3

* Drop UADT meta-analyses from Head and Neck (excl. pooled project)
drop if Cancer==1 & Outcome=="UADT"

* Kidney
replace count=15 if Outcome=="Kidney cancer" & Exposure=="Alcohol (as ethanol)" & count==4
replace count=14 if Outcome=="Kidney cancer" & Exposure=="Cruciferous vegetables" & count==2
replace count=15 if Outcome=="Kidney cancer" & Exposure=="Processed Meat" & count==3
replace count=15 if Outcome=="Kidney cancer" & Exposure=="Citrus Fruit" & count==3
replace count=16 if Outcome=="Kidney cancer" & Exposure=="Coffee" & count==5
replace count=14 if Outcome=="Kidney cancer" & Exposure=="Red meat" & count==2
replace count=14 if Outcome=="Kidney cancer" & Exposure=="Tomatoes" & count==2
replace count=15 if Outcome=="Kidney cancer" & Exposure=="Vegetables" & count==3
replace count=14 if Outcome=="Kidney cancer" & Exposure=="Non-starchy vegetables and fruits" & count==2
replace count=15 if Outcome=="Kidney cancer" & Exposure=="Fruit" & count==3
replace count=15 if Outcome=="Kidney cancer" & Exposure=="Poultry" & count==3
replace count=14 if Outcome=="Kidney cancer women" & Exposure=="Tea" & count==2

* Lung
replace count=14 if Outcome=="Lung cancer Adenocarcinoma" & Exposure=="Ethanol" & count==6
replace count=15 if Outcome=="Lung cancer" & Exposure=="Wine" & count==7
replace count=16 if Outcome=="Lung cancer" & Exposure=="Liquors" & count==8
replace count=13 if Outcome=="Lung cancer nonsmokers" & Exposure=="Ethanol" & count==5
replace count=8 if Outcome=="Lung cancer women" & Exposure=="Beer" & count==3
replace count=12 if Outcome=="Lung cancer Small cell carcinoma" & Exposure=="Ethanol" & count==4
replace count=8 if Outcome=="Lung cancer men" & Exposure=="Beer" & count==5
replace count=17 if Outcome=="Lung cancer" & Exposure=="Beer" & count==9
replace count=13 if Outcome=="Lung cancer current smokers" & Exposure=="Ethanol" & count==5
replace count=16 if Outcome=="Lung cancer incidence" & Exposure=="Beer" & count==8
replace count=13 if Outcome=="Lung cancer" & Exposure=="Total fat" & count==6
replace count=14 if Outcome=="Lung cancer Squamous cell" & Exposure=="Ethanol" & count==6

*********************************************************	
* 		Unconditional power 		        *
* (this is the starting point of the conditional power) *
*********************************************************
	
quietly gen reDelta=. 
quietly gen re_up=.
quietly gen tau_old=.
quietly gen tau_new=. 

quietly levelsof compid, local(compid6)
	
	foreach i of local compid6 {  
	
quietly replace reDelta=log(Study_RE_RR) if compid==`i'
quietly replace re_up=1-normal(invnormal(0.975)-(reDelta*sqrt(reW_sum)))+ ///
normal(-invnormal(0.975)-(reDelta*sqrt(reW_sum))) if compid==`i'

* Impute re_up as 10% when missing UP 
quietly replace re_up=0.09999 if re_up==. & compid==`i'		

* A priori stated future studies will have similar heterogeneity as observed studies
quietly replace tau_old=tau if compid==`i'
quietly replace tau_new=tau_old if compid==`i'

}

*******************************************
* Weights of the existing and new studies * 
*******************************************

* The revised weight awarded to an existing study
quietly gen reW_rev=. 	
quietly gen reW_rev_sum=.

* The weight assigned to a new study
quietly gen reW_new=.	
quietly gen reW_new_sum=.

quietly levelsof compid, local(compid6)

	foreach i of local compid6 {
	
quietly replace reW_rev=feW/(1+feW*tau_new) if compid==`i'
quietly sum reW_rev if compid==`i'
quietly replace reW_rev_sum=r(sum) if compid==`i'
quietly replace reW_new=feW_bar/(1+feW_bar*tau_new) if compid==`i'
quietly sum reW_new if compid==`i'
quietly replace reW_new_sum=r(sum) if compid==`i'

}

*********************
* Conditional power *
*********************

* The number of future studies needed for 80% power; a priori stated that will be of average weight
quietly gen reM=0           

* Setting the starting value of conditional power
quietly gen reCp=re_up

quietly gen tau_all=.
quietly gen reWY_rev=.
quietly gen reWY_rev_sum=. 
quietly gen temp_var=.

* Conditional power will be calculated using the following 5 terms
quietly gen reterm1=-999
quietly gen reterm2=-999
quietly gen reterm3=-999
quietly gen reterm4=-999
quietly gen reterm5=-999

quietly levelsof compid if prandom>=0.05 & reDelta!=0, local(compid7)

	foreach i of local compid7 {
		quietly levelsof reCp if compid==`i', local(reCp_levels)
			while (`reCp_levels'<0.8) {
		
quietly replace reM=reM+1 if compid==`i' 
quietly replace tau_all=((count/(count+reM))*tau_new)+((reM/(count+reM))*tau_new) if compid==`i'  																												
quietly replace reterm1=sqrt((reM+(tau_all*reW_new))/(reM*reW_new)) if compid==`i'

quietly replace reW_rev=feW/(1+feW*tau_all) if compid==`i'
quietly sum reW_rev if compid==`i'
quietly replace reW_rev_sum=r(sum) if compid==`i'
quietly replace reterm2=reW_rev_sum if compid==`i'	 										
														
quietly replace reterm3=reM*reW_new/(reM+(reW_new*tau_all)) if compid==`i'

quietly replace reWY_rev=reW_rev*Study_logRR if compid==`i'
quietly sum reWY_rev if compid==`i'
quietly replace reWY_rev_sum=r(sum) if compid==`i'
quietly replace reterm4=reWY_rev_sum if compid==`i'
			
quietly replace reterm5=reM*reDelta/(sqrt((reM/reW_new)+(reM*tau_all))) if compid==`i'

quietly replace temp_var=normal(-reterm1*((invnormal(0.975)*sqrt(reterm2+reterm3))-reterm4)+reterm5) ///
	+normal(-reterm1*((invnormal(0.975)*sqrt(reterm2+reterm3))+reterm4)-reterm5) if compid==`i'
		
quietly levelsof temp_var if compid==`i', local(temp_var)
quietly local reCp_levels=`temp_var'
	
	}
quietly replace reCp=`reCp_levels' if compid==`i'

}

quietly levelsof compid if prandom>=0.05 & reDelta==0, local(compid8)
	foreach i of local compid8 {
	
quietly replace reM=-999 if compid==`i'
quietly replace reCp=-999 if compid==`i'

}

********************************************************************************
********************************************************************************
**** 		Conditional power using the largest study RR                ****
********************************************************************************
********************************************************************************

***********************
* Unconditional power *
***********************

quietly gen re_up_largstu=. 

quietly levelsof compid, local(compid9)	
	foreach i of local compid9 {  

quietly replace re_up_largstu=1-normal(invnormal(0.975)-(log_effect_largstu*sqrt(reW_sum)))+ ///
normal(-invnormal(0.975)-(log_effect_largstu*sqrt(reW_sum))) if compid==`i'
quietly replace re_up_largstu=0.09999 if re_up_largstu==. & compid==`i'		

}

*********************
* Conditional power *
*********************

quietly gen reM_largstu=0           
quietly gen reCp_largstu=re_up_largstu
quietly gen tau_all_largstu=.
quietly gen reW_rev_largstu=.
quietly gen reW_rev_largstu_sum=.
quietly gen reWY_rev_largstu=.
quietly gen reWY_rev_largstu_sum=. 
quietly gen temp_var_largstu=.

quietly gen reterm6=-999
quietly gen reterm7=-999
quietly gen reterm8=-999
quietly gen reterm9=-999
quietly gen reterm10=-999

quietly levelsof compid if prandom>=0.05 & log_effect_largstu!=0, local(compid10)
	foreach i of local compid10 {
		quietly levelsof reCp_largstu if compid==`i', local(reCp_largstu_levels)
			while (`reCp_largstu_levels'<0.8) {
		
quietly replace reM_largstu=reM_largstu+1 if compid==`i' 
quietly replace tau_all_largstu=((count/(count+reM_largstu))*tau_new)+((reM_largstu/(count+reM_largstu))*tau_new) if compid==`i'  																												
quietly replace reterm6=sqrt((reM_largstu+(tau_all_largstu*reW_new))/(reM_largstu*reW_new)) if compid==`i'

quietly replace reW_rev_largstu=feW/(1+feW*tau_all_largstu) if compid==`i'
quietly sum reW_rev_largstu if compid==`i'
quietly replace reW_rev_largstu_sum=r(sum) if compid==`i'
quietly replace reterm7=reW_rev_largstu_sum if compid==`i'	 										
														
quietly replace reterm8=reM_largstu*reW_new/(reM_largstu+(reW_new*tau_all_largstu)) if compid==`i'

quietly replace reWY_rev_largstu=reW_rev_largstu*Study_logRR if compid==`i'
quietly sum reWY_rev_largstu if compid==`i'
quietly replace reWY_rev_largstu_sum=r(sum) if compid==`i'
quietly replace reterm9=reWY_rev_largstu_sum if compid==`i'
			
quietly replace reterm10=reM_largstu*log_effect_largstu/(sqrt((reM_largstu/reW_new)+(reM_largstu*tau_all_largstu))) if compid==`i'

quietly replace temp_var_largstu=normal(-reterm6*((invnormal(0.975)*sqrt(reterm7+reterm8))-reterm9)+reterm10) ///
+normal(-reterm6*((invnormal(0.975)*sqrt(reterm7+reterm8))+reterm9)-reterm10) if compid==`i'
		
quietly levelsof temp_var_largstu if compid==`i', local(temp_var_largstu)
quietly local reCp_largstu_levels=`temp_var_largstu'
	
	}

quietly replace reCp_largstu=`reCp_largstu_levels' if compid==`i'

}

quietly levelsof compid if prandom>=0.05 & log_effect_largstu==0, local(compid11)
	foreach i of local compid11 {
	
quietly replace reM_largstu=-999 if compid==`i'
quietly replace reCp_largstu=-999 if compid==`i'

}

********************************************************************************
********************************************************************************
***			Fail-safe number			 	     ***
***	 Rosenberg's approach; the number of future studies with an average  ***	
***	 null effect and average weight (i.e., inverse variance), needed to  ***
***	 drive the existing meta-analyses summary estimates to null in the   ***
***	 updated meta-analysis						     ***
********************************************************************************
********************************************************************************

quietly gen reWprime=.
quietly gen RE_R_FSN=.

quietly levelsof compid if prandom<0.05, local(compid12)
	foreach i of local compid12 {
	
quietly replace reWprime=((reWY_sum^2)/(invnormal(0.975)^2))-reW_sum if compid==`i'
quietly replace RE_R_FSN=(reWprime*count)/reW_sum if compid==`i'
quietly replace RE_R_FSN=ceil(RE_R_FSN) if compid==`i'

}

* Individual meta-analyses per row
quietly gsort compid se -No_cases
quietly by compid: keep if _n==1

********************************************************************************
********************************************************************************
***			Display results					     ***
********************************************************************************
********************************************************************************

* Descriptives by cancer group (Table 1)
tabstat count total_N total_Cases if Cancer!=1, stats(p50 min max) by(Cancer) ///
columns(variables) long format(%9.0f)

* Descriptives by cancer group & evidence grade criteria (Table 2)
tab Cancer if prandom<1E-06 & Cancer!=1
tab Cancer if prandom<1E-03 & Cancer!=1 
tab Cancer if prandom<0.05 & Cancer!=1
tab Cancer if I2>50 & Cancer!=1
tab Cancer if I2<=25 & Cancer!=1
tab Cancer if ((pred_ll>1 & pred_ul>1) | ///
(pred_ll<1 & pred_ul<1)) & pred_ll<. & pred_ul<. & Cancer!=1
tab Cancer if (egger_p<=0.1 & ///
abs(log(effectrandom))>=abs(log(effect_largstu))) & Cancer!=1
tab Cancer if pBin1<=0.1 & Cancer!=1
tab Cancer grade if Cancer!=1, column

* Descriptives by wider exposure categories (Supplementary Table 3)
tabstat count total_N total_Cases if Cancer!=1, stats(p50 min max) by(Exposure_wider) ///
columns(variables) long format(%9.0f)

* Descriptives by wider exposure categories & evidence grade criteria (Supplementary Table 4)
tab Exposure_wider if prandom<1E-06 & Cancer!=1
tab Exposure_wider if prandom<1E-03 & Cancer!=1 
tab Exposure_wider if prandom<0.05 & Cancer!=1
tab Exposure_wider if I2>50 & Cancer!=1
tab Exposure_wider if I2<=25 & Cancer!=1
tab Exposure_wider if ((pred_ll>1 & pred_ul>1) | ///
(pred_ll<1 & pred_ul<1)) & pred_ll<. & pred_ul<. & Cancer!=1
tab Exposure_wider if (egger_p<=0.1 & ///
abs(log(effectrandom))>=abs(log(effect_largstu))) & Cancer!=1
tab Exposure_wider if pBin1<=0.1 & Cancer!=1
tab Exposure_wider grade if Cancer!=1, column

* Supplementary table 5
sort Cancer grade prandom
label var Exposure_contrast "Exposure contrast"
label var count "No of Studies"
gen randomeffects=string(effectrandom,"%9.2f") + ///
" (" + string(effectrandom_l,"%9.2f") +", " + ///
string(effectrandom_u,"%9.2f") + ")"
label var randomeffects "Random effects RR (95% CI)"
label var prandom "Random effects P-value"
gen largeststudy=string(effect_largstu,"%9.2f") + ///
" (" + string(effect_largstu_l,"%9.2f") +", " + ///
string(effect_largstu_u,"%9.2f") + ")"
label var largeststudy "Largest study RR (95% CI)"
replace I2=ceil(I2)
export excel Outcome Exposure Exposure_contrast count randomeffects prandom ///
largeststudy I2 reM reM_largstu if prandom>0.05 & ((reM<count & reM>0 & reM<.) | ///
(reM_largstu<count & reM_largstu>0 & reM_largstu<.)) using STable5.xls, ///
firstrow(varlabels)

* Supplementary table 1
gen ncases_population=string(total_Cases) + "/" + string(total_N)
label var ncases_population "Cases/Population"
label var grade "Grading of the evidence"
label var reM "CP-Random effects RR"
tostring reM, replace force
replace reM="NA" if reM=="0" | reM=="-999"
label var reM_largstu "CP-Largest study RR"
tostring reM_largstu, replace force
replace reM_largstu="NA" if reM_largstu=="0" | reM_largstu=="-999"
label var RE_R_FSN "Rosenberg's fail-safe number"
tostring RE_R_FSN, replace force
replace RE_R_FSN="NA" if RE_R_FSN=="."
export excel Outcome Exposure Exposure_contrast count ncases_population ///
randomeffects prandom largeststudy grade reM reM_largstu RE_R_FSN using STable1.xls, ///
firstrow(varlabels)

* Supplementary table 2
gen egger_pvalue=string(egger_p, "%9.3f")
replace egger_pvalue=".0000394" if compid==834
replace egger_pvalue=".0001675" if compid==16
replace egger_pvalue=".0000443" if compid==238
replace egger_pvalue=".0003978" if compid==232
replace egger_pvalue="NA" if egger_pvalue=="."
label var egger_pvalue "Egger's P-value"
gen predictioninterval=string(pred_ll,"%9.2f") +", " ///
+ string(pred_ul,"%9.2f")
replace predictioninterval="NA" if predictioninterval=="., ."
label var predictioninterval "95% PI"
gen excess_o_e1=string(Observed1) + "/" + string(Expected1,"%9.2f")
label var excess_o_e1 "Observed/Expected"
tostring pBin1, replace force
replace pBin1="NP" if pBin1=="."
label var pBin1 "ES P-value"
export excel Outcome Exposure Exposure_contrast count grade I2 ///
predictioninterval egger_pvalue excess_o_e1 pBin1 using Table2.xls, ///
firstrow(varlabels)
